/**
 * @date 2015年12月24日 下午7:15:34
 * @version V1.0
 */
package Commons;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;


/**
 * @ClassName: topic_model_process
 * @Description: TODO
 * @author ffftzh
 * @date 2015年12月24日 下午7:15:34
 *
 */
public class topic_model_process {
    double[] TopicProbroty = null;
    ArrayList<ArrayList<Double>> phi = new ArrayList<ArrayList<Double>>();
    int wordCount = 0;

    public void getTopicProb(String thetaPath) throws NumberFormatException, IOException {

        BufferedReader reader = IOUtil.getReader(thetaPath);
        String line = null;
        int docCount = 0;
        while ((line = reader.readLine()) != null) {
            docCount++;
            String[] lines = line.split("\\s+");
            if (TopicProbroty == null) {
                TopicProbroty = new double[lines.length];
            }
            for (int i = 0; i < lines.length; i++) {
                TopicProbroty[i] += Double.parseDouble(lines[i]);
            }

        }
        for (int i = 0; i < TopicProbroty.length; i++) {
            TopicProbroty[i] /= docCount;
        }

    }

    void getTopicProb(String assignpath, int k) throws NumberFormatException, IOException {
        TopicProbroty = new double[k];

        wordCount = k;
        BufferedReader reader = IOUtil.getReader(assignpath);
        String lineString = null;
        while ((lineString = reader.readLine()) != null) {
            String[] linelist = lineString.split("\\s+");
            for (int i = 0; i < linelist.length; i++) {
                wordCount++;
                int topic_num = Integer.parseInt(linelist[i].split(":")[1]);
                TopicProbroty[topic_num] += 1;
            }
        }
        for (int i = 0; i < k; i++) {
            TopicProbroty[i] /= wordCount;
        }
        reader.close();
    }


    void getPhi(String phiPath) throws NumberFormatException, IOException {
        BufferedReader reader = IOUtil.getReader(phiPath);
        String lineString = null;
        while ((lineString = reader.readLine()) != null) {
            String[] linelist = lineString.trim().split("\\s+");
            ArrayList<Double> tmpline = new ArrayList<Double>();
            for (int i = 0; i < linelist.length; i++) {
                tmpline.add(Double.parseDouble(linelist[i]));
            }
            phi.add(tmpline);
        }
        reader.close();
    }

    private void doProcess(String assignPath) throws NumberFormatException, IOException {
        //ArrayList<Double> oneLineResult = new ArrayList<Double>();
        BufferedReader reader = IOUtil.getReader(assignPath);
        BufferedWriter writer = IOUtil.getWriter(assignPath + ".word_theta");
        String lineString = null;
        while ((lineString = reader.readLine()) != null) {
            String[] linelist = lineString.split("\\s+");

            HashMap<Integer, Integer> assign = new HashMap<Integer, Integer>();
            for (int i = 0; i < linelist.length; i++) {
                int wordId = Integer.parseInt(linelist[i].split(":")[0]);
                if (!assign.containsKey(wordId)) {
                    assign.put(wordId, 0);
                }
                assign.put(wordId, assign.get(wordId) + 1);
            }


            for (int k = 0; k < TopicProbroty.length; k++) {
                double finalOne = 0.0;
                for (int wordId : assign.keySet()) {
                    Double alpha = (double) assign.get(wordId) / linelist.length;
                    finalOne += getPzw(k, wordId) * alpha;
                }
                writer.write(finalOne + " ");
            }
            writer.write("\n");
        }
        reader.close();
        writer.close();


    }

    private Double getPzw(int k, int wordId) {
        double result = 0.0;
        result = TopicProbroty[k] * phi.get(k).get(wordId);
        double chushu = 0.0;
        for (int i = 0; i < TopicProbroty.length; i++) {
            chushu += TopicProbroty[i] * phi.get(i).get(wordId);
        }
        return result / chushu;
    }

    public void generate_indirect_present_V2(String doc, String phiPath, String thetaPath, String wordmap) throws IOException {

        getTopicProb(thetaPath);
        getPhi(phiPath);
        doProcess_v2(doc, wordmap, thetaPath);
    }

    private void doProcess_v2(String doc, String wordmap, String thetaPath) throws NumberFormatException, IOException {
        //ArrayList<Double> oneLineResult = new ArrayList<Double>();
        HashMap<String, Integer> twordmap = new HashMap<String, Integer>();
        BufferedWriter writer = IOUtil.getWriter(thetaPath + ".word_theta");
        BufferedReader reader = IOUtil.getReader(wordmap);
        String lineString = null;
        while ((lineString = reader.readLine()) != null) {
            String[] linelist = lineString.split("\\s+");
            twordmap.put(linelist[0], Integer.parseInt(linelist[1]));
        }
        reader.close();
        reader = IOUtil.getReader(doc);
        lineString = null;

        while ((lineString = reader.readLine()) != null) {
            String[] linelist = lineString.split("\\s+");

            HashMap<Integer, Integer> assign = new HashMap<Integer, Integer>();
            for (int i = 0; i < linelist.length; i++) {
                int wordId = twordmap.get(linelist[i]);
                if (!assign.containsKey(wordId)) {
                    assign.put(wordId, 0);
                }
                assign.put(wordId, assign.get(wordId) + 1);
            }


            for (int k = 0; k < TopicProbroty.length; k++) {
                double finalOne = 0.0;
                for (int wordId : assign.keySet()) {
                    Double alpha = (double) assign.get(wordId) / linelist.length;
                    finalOne += getPzw(k, wordId) * alpha;
                }
                writer.write(finalOne + " ");
            }
            writer.write("\n");
        }
        reader.close();
        writer.close();

    }

    public void generate_indirect_present(String phiPath, String assignPath, int k) throws IOException {

        getTopicProb(assignPath, k);
        getPhi(phiPath);
        doProcess(assignPath);
    }

    public static HashMap<String, Integer> get_word_dict(String[] lines) {
        HashMap<String, Integer> result = new HashMap<String, Integer>();
        for (String Item : lines) {
            String[] pitem = Item.split(":");
            if (!result.containsKey(pitem[1])) {
                result.put(pitem[1], 0);
            }
            result.put(pitem[1], result.get(pitem[1]) + 1);
        }
        return result;
    }

    public static void new_assign(String assign, String data_path, String wordmap_path) throws IOException {
        HashMap<String, String> wordmap = new HashMap<String, String>();
        BufferedReader reader = IOUtil.getReader(wordmap_path);
        String lineString = null;
        while ((lineString = reader.readLine()) != null) {
            String[] lines = lineString.split("\\s+");
            wordmap.put(lines[0], lines[1]);
        }
        reader.close();
        ArrayList<String> AssignList = new ArrayList<String>();
        reader = IOUtil.getReader(assign);
        lineString = null;
        while ((lineString = reader.readLine()) != null) {
            AssignList.add(lineString.trim());
        }
        reader.close();

        BufferedWriter new_assign_writer = IOUtil.getWriter(assign + ".assign");
        reader = IOUtil.getReader(data_path);
        lineString = null;
        int index = 0;
        while ((lineString = reader.readLine()) != null) {
            String[] lines = lineString.split("\\s+");
            String write_tk = "";
            for (String one_item : lines) {
                write_tk += wordmap.get(one_item) + ":" + AssignList.get(index) + " ";
            }
            index++;
            new_assign_writer.write(write_tk.trim() + "\n");

        }
        new_assign_writer.close();
        reader.close();

    }

    public static void generate_theta(String assign_path, int topic_num, double alpha) throws IOException {
        BufferedReader reader = IOUtil.getReader(assign_path);
        BufferedWriter writer = IOUtil.getWriter(assign_path + ".theta");
        String lineString = null;
        while ((lineString = reader.readLine()) != null) {
            String[] lines = lineString.split("\\s+");
            HashMap<String, Integer> topiclist = get_word_dict(lines);
            for (int i = 0; i < topic_num; i++) {
                if (!topiclist.containsKey(i + "")) {
                    writer.write((alpha / (lines.length + topic_num * alpha)) + " ");
                } else {
                    writer.write(((alpha + topiclist.get(i + "")) / (lines.length + topic_num * alpha)) + " ");
                }
            }
            writer.write("\n");
        }
        reader.close();
        writer.close();
    }


    public static void main(String[] args) throws IOException {
        int NKL = 5;
        String[] dirStrings = {"LDA", "PAM4ST", "PA_SATM", "unigram", "DsparseTM", "AliasPAM4ST_1000_100_0.001_0.1_0.01"};
        String[] theta = {};
        String[] word_theta = {};
        String[] phiStrings = {"model-final.phi", "phi.txt", "phi_1500.txt", "mu_phi_1.txt", "model-final.phi", "model-2000.phi"};
        String[] assignStrings = {"model-final.tassign", "zassign.txt", "zassign_1500.txt", "assign.txt.assign", "model-final.tassign", "model-2000.tassign"};


//		for(int i=0;i<5;i++)
//		{	String rootroot = "data2/QA_Q/";
//			String uniroot =rootroot+"unigram/"+i+"/";
//			new_assign(uniroot+"assign.txt", rootroot+"yahoo_question.txt.pd.filter.final.10", uniroot+"mu_wordmap.txt");
//		}
//	
//		for(int i=0;i<5;i++){
//			String rootroot = "data4/new-tweet/"+dirStrings[NKL]+"/"+i+"/";
//			generate_theta(rootroot+assignStrings[NKL],100,0.1);
//		}

        String[] DataList = {
                "news",
                "dblp-6",
                "new-tweet",
                "baiduQA"
        };
        for (String dataName : DataList) {
            for (int i = 0; i < 5; i++) {
                topic_model_process inffModel_process = new topic_model_process();
                String rootPath = "data4/" + dataName + "/DsparseTM/" + i + "/";
                inffModel_process.generate_indirect_present_V2("data4/" + dataName + "/" + dataName + ".data",
                        rootPath + "model-final.phi", rootPath + "model-final.theta", rootPath + "wordmap.txt");
            }
        }


        //inffModel_process.generate_indirect_present(rootPath+phiStrings[NKL],rootPath+assignStrings[NKL],100);
        //inffModel_process.generate_indirect_present("data2/www_2008/SATM/4/phi_500.txt","data2/www_2008/SATM/4/zassign_500.txt",100);


    }
}
